package com.senlingspace.system.service.impl;

import com.alibaba.fastjson2.JSON;
import com.google.common.base.Stopwatch;
import com.senlingspace.common.core.redis.RedisCache;
import com.senlingspace.system.domain.dto.AreaDTO;
import com.senlingspace.system.mapper.SysAreaMapper;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 省市区联动
 *
 * @author lebronjames
 * @date 2024/09/10
 */
@Slf4j
@Service
@AllArgsConstructor
public class SysAreaService {

    public final static String AREA_KEY = "areas";
    public final static String MINI_APP_AREA_KEY = "mini_app_areas";

    private final SysAreaMapper sysAreaMapper;
    private final RedisCache redisCache;


    public String getAreaTree() {
        if (redisCache.hasKey(AREA_KEY)) {
            log.info("从缓存中获取省市区数据！");
            return redisCache.getCacheObject(AREA_KEY);
        }

        Stopwatch stopwatch = Stopwatch.createStarted();
        List<AreaDTO> areaList = sysAreaMapper.findAllAreas();

        List<AreaDTO> nullList = areaList.stream()
                .filter(area -> area.getCityId() == null)
                .collect(Collectors.toList());
        log.info("nullList：{}", JSON.toJSONString(nullList));

        // 将 AreaDTO 按省份 -> 城市 -> 区域 进行分组
        Map<Integer, Map<Integer, List<AreaDTO>>> provinceCityDistrictMap = areaList.stream()
                .collect(Collectors.groupingBy(AreaDTO::getProvinceId,
                        Collectors.groupingBy(AreaDTO::getCityId)));

        // 构建层级结构
        List<Map<String, Object>> result = provinceCityDistrictMap.entrySet().stream().map(provinceEntry -> {
            Map<String, Object> provinceMap = new HashMap<>();
            Integer provinceId = provinceEntry.getKey();
            List<AreaDTO> cityList = provinceEntry.getValue().values().stream().flatMap(List::stream).collect(Collectors.toList());
            String provinceName = cityList.get(0).getProvinceName();
            // 省
            provinceMap.put("value", provinceId);
            provinceMap.put("label", provinceName);

            List<Map<String, Object>> cities = provinceEntry.getValue().entrySet().stream().map(cityEntry -> {
                Map<String, Object> cityMap = new HashMap<>();
                Integer cityId = cityEntry.getKey();
                List<AreaDTO> districts = cityEntry.getValue();
                String cityName = districts.get(0).getCityName();
                // 市
                cityMap.put("value", cityId);
                cityMap.put("label", cityName);

                List<Map<String, Object>> districtList = districts.stream().map(district -> {
                    Map<String, Object> districtMap = new HashMap<>();
                    // 区
                    districtMap.put("value", district.getDistrictId());
                    districtMap.put("label", district.getDistrictName());
                    // 全称 (省份+城市+区域)
                    districtMap.put(" fullName", district.getFullName());
                    return districtMap;
                }).collect(Collectors.toList());

                cityMap.put("children", districtList);
                return cityMap;
            }).collect(Collectors.toList());

            provinceMap.put("children", cities);
            return provinceMap;
        }).collect(Collectors.toList());

        log.info("从数据库中获取省市区数据！耗时：{}", stopwatch.stop());
        String json = JSON.toJSONString(result);
        redisCache.setCacheObject(AREA_KEY, json);
        return json;

    }

    public String getMiniAppAreaTree() {
        if (redisCache.hasKey(MINI_APP_AREA_KEY)) {
            log.info("从缓存中获取省市区数据！");
            return redisCache.getCacheObject(MINI_APP_AREA_KEY);
        }

        Stopwatch stopwatch = Stopwatch.createStarted();
        List<AreaDTO> areaList = sysAreaMapper.findAllAreas();

        List<AreaDTO> nullList = areaList.stream()
                .filter(area -> area.getCityId() == null)
                .collect(Collectors.toList());
        log.info("nullList：{}", JSON.toJSONString(nullList));

        // 将 AreaDTO 按省份 -> 城市 -> 区域 进行分组
        Map<Integer, Map<Integer, List<AreaDTO>>> provinceCityDistrictMap = areaList.stream()
                .collect(Collectors.groupingBy(AreaDTO::getProvinceId,
                        Collectors.groupingBy(AreaDTO::getCityId)));

        // 构建层级结构
        List<Map<String, Object>> result = provinceCityDistrictMap.entrySet().stream().map(provinceEntry -> {
            Map<String, Object> provinceMap = new HashMap<>();
            Integer provinceId = provinceEntry.getKey();
            List<AreaDTO> cityList = provinceEntry.getValue().values().stream().flatMap(List::stream).collect(Collectors.toList());
            String provinceName = cityList.get(0).getProvinceName();
            // 省
            provinceMap.put("value", provinceId);
            provinceMap.put("text", provinceName);

            List<Map<String, Object>> cities = provinceEntry.getValue().entrySet().stream().map(cityEntry -> {
                Map<String, Object> cityMap = new HashMap<>();
                Integer cityId = cityEntry.getKey();
                List<AreaDTO> districts = cityEntry.getValue();
                String cityName = districts.get(0).getCityName();
                // 市
                cityMap.put("value", cityId);
                cityMap.put("text", cityName);

                List<Map<String, Object>> districtList = districts.stream().map(district -> {
                    Map<String, Object> districtMap = new HashMap<>();
                    // 区
                    districtMap.put("value", district.getDistrictId());
                    districtMap.put("text", district.getDistrictName());
                    // 全称 (省份+城市+区域)
                    districtMap.put(" fullName", district.getFullName());
                    return districtMap;
                }).collect(Collectors.toList());

                cityMap.put("children", districtList);
                return cityMap;
            }).collect(Collectors.toList());

            provinceMap.put("children", cities);
            return provinceMap;
        }).collect(Collectors.toList());

        log.info("从数据库中获取省市区数据！耗时：{}", stopwatch.stop());
        String json = JSON.toJSONString(result);
        redisCache.setCacheObject(MINI_APP_AREA_KEY, json);
        return json;

    }

}
